{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Mat A, C;                          // creates just the header parts\n",
    "A = imread(argv[1], IMREAD_COLOR); // here we'll know the method used (allocate matrix)\n",
    "Mat B(A);                                 // Use the copy constructor\n",
    "C = A;                                    // Assignment operator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All the above objects, in the end, point to the same single data matrix and making a modification using any of them will affect all the other ones as well. \n",
    "Nevertheless, their header parts are different. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " For example, to create a region of interest (ROI) in an image you just create a new header with the new boundaries:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle\n",
    "Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now you may ask – if the matrix itself may belong to multiple Mat objects, who takes responsibility for cleaning it up when it's no longer needed? The short answer is: the last object that used it. This is handled by using a reference counting mechanism. Whenever somebody copies a header of a Mat object, a counter is increased for the matrix. Whenever a header is cleaned, this counter is decreased. When the counter reaches zero the matrix is freed. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "深拷贝图像  \n",
    "Sometimes you will want to copy the matrix itself too, so OpenCV provides cv::Mat::clone() and cv::Mat::copyTo() functions.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Mat F = A.clone();\n",
    "Mat G;\n",
    "A.copyTo(G);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Storing methods  \n",
    "RGB is the most common as our eyes use something similar, however keep in mind that OpenCV standard display system composes colors using the BGR color space (red and blue channels are swapped places).  \n",
    "\n",
    "The HSV and HLS decompose colors into their hue, saturation and value/luminance components, which is a more natural way for us to describe colors. You might, for example, dismiss the last component, making your algorithm less sensible to the light conditions of the input image.  \n",
    " \n",
    "YCrCb is used by the popular JPEG image format.  \n",
    "\n",
    "CIE L*a*b* is a perceptually uniform color space, which comes in handy if you need to measure the distance of a given color to another color."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Creating a Mat object explicitly  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//cv::Mat::Mat Constructor\n",
    "Mat M(2,2, CV_8UC3, Scalar(0,0,255));\n",
    "cout << \"M = \" << endl << \" \" << M << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use C/C++ arrays and initialize via constructor\n",
    "\n",
    "    int sz[3] = {2,2,2};\n",
    "    Mat L(3,sz, CV_8UC(1), Scalar::all(0));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "cv::Mat::create function:   \n",
    "\n",
    "    M.create(4,4, CV_8UC(2));\n",
    "    cout << \"M = \"<< endl << \" \"  << M << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MATLAB style initializer: cv::Mat::zeros , cv::Mat::ones , cv::Mat::eye . Specify size and data type to use:  \n",
    "\n",
    "    Mat E = Mat::eye(4, 4, CV_64F);\n",
    "    cout << \"E = \" << endl << \" \" << E << endl << endl;\n",
    "    Mat O = Mat::ones(2, 2, CV_32F);\n",
    "    cout << \"O = \" << endl << \" \" << O << endl << endl;\n",
    "    Mat Z = Mat::zeros(3,3, CV_8UC1);\n",
    "    cout << \"Z = \" << endl << \" \" << Z << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For small matrices you may use comma separated initializers or initializer lists (C++11 support is required in the last case):  \n",
    "\n",
    "    Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);\n",
    "    cout << \"C = \" << endl << \" \" << C << endl << endl;\n",
    "    C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);\n",
    "    cout << \"C = \" << endl << \" \" << C << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a new header for an existing Mat object and cv::Mat::clone or cv::Mat::copyTo it.  \n",
    "    Mat RowClone = C.row(1).clone();\n",
    "    cout << \"RowClone = \" << endl << \" \" << RowClone << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can fill out a matrix with random values using the cv::randu() function. You need to give a lower and upper limit for the random values:  \n",
    "\n",
    "    Mat R = Mat(3, 2, CV_8UC3);\n",
    "    randu(R, Scalar::all(0), Scalar::all(255));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Output formatting  \n",
    "可以输出numpy等等格式\n",
    "Python\n",
    "    cout << \"R (python)  = \" << endl << format(R, Formatter::FMT_PYTHON) << endl << endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Output of other common items  \n",
    "转成opencv的点以及mat格式后，可以使用<<很方便输出需要的内容\n",
    "\n",
    "2D Point\n",
    "    Point2f P(5, 1);\n",
    "    cout << \"Point (2D) = \" << P << endl << endl;\n",
    "\n",
    "3D Point\n",
    "    Point3f P3f(2, 6, 7);\n",
    "    cout << \"Point (3D) = \" << P3f << endl << endl;\n",
    "\n",
    "std::vector via cv::Mat\n",
    "    vector<float> v;\n",
    "    v.push_back( (float)CV_PI);   v.push_back(2);    v.push_back(3.01f);\n",
    "    cout << \"Vector of floats via Mat = \" << Mat(v) << endl << endl;\n",
    "\n",
    "std::vector of points\n",
    "    vector<Point2f> vPoints(20);\n",
    "    for (size_t i = 0; i < vPoints.size(); ++i)\n",
    "        vPoints[i] = Point2f((float)(i * 5), (float)(i % 7));\n",
    "    cout << \"A vector of 2D Points = \" << vPoints << endl << endl;\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
